#ifndef quantlib_pricingengines_i
#define quantlib_pricingengines_i

%include zz_models.i
%include common.i
%include types.i
%include functions.i
%include <pyabc.i>


%{
using QuantLib::AnalyticHestonEngine;
using QuantLib::GenericModelEngine;
using QuantLib::VanillaOption;
typedef boost::shared_ptr<GenericModelEngine<HestonModel, VanillaOption::arguments, VanillaOption::results> > AnalyticHestonEnginePtr;
%}

//~ %ignore PricingEngine;
//~ class PricingEngine {
	//~ private:
		//~ PricingEngine();
//~ };


template <class T, class U, class V>
class GenericModelEngine {
	private:
		GenericModelEngine(const boost::shared_ptr<T>& = boost::shared_ptr<T>());
		virtual void calculate(){};
    //boost::shared_ptr<T, U, V> operator->();
};


%template(GenericModelEngineImpl) GenericModelEngine<HestonModel, VanillaOption::arguments, VanillaOption::results>;
%template(GenericModelEngine) boost::shared_ptr<GenericModelEngine<HestonModel, VanillaOption::arguments, VanillaOption::results> >;
//%template(GenericModelEngine) boost::shared_ptr<GenericModelEngine>;

//~ %{
//~ typedef boost::shared_ptr<GenericModelEngine<HestonModel, VanillaOption::arguments, VanillaOption::results> > AnalyticHestonEnginePtr;
//~ %}

%rename(AnalyticHestonEngine) AnalyticHestonEnginePtr;
class AnalyticHestonEnginePtr : public boost::shared_ptr<GenericModelEngine<HestonModel, VanillaOption::arguments, VanillaOption::results> > {
	public:
		%extend {
			AnalyticHestonEnginePtr(const HestonModelPtr& proc){
				const boost::shared_ptr<HestonModel>& process =
					boost::dynamic_pointer_cast<HestonModel>(proc);
				return new AnalyticHestonEnginePtr(new AnalyticHestonEngine(process));
			}
			
			// static void doCalculation(
				 // Real riskFreeDiscount,
				 // Real dividendDiscount,
				 // Real spotPrice,
				 // Real strikePrice,
				 // Real term,
				 // Real kappa, Real theta, Real sigma, Real v0, Real rho,
				 // const TypePayoff& type,
				 // const Integration& integration,
				 // const ComplexLogFormula cpxLog,
				 // const AnalyticHestonEngine* const enginePtr,
				 // Real& value,
				 // Size& evaluations
			// ) {
			// };
			
			
			// void calculate(){(*self)->calculate();}
			
			// Real getNPV(){return (*self)->getResults()->value();}
		}
};

#endif